//! 生命周期lifetime的作用：
//! 1. 用于ref上，比如&'a T
//! 2. 用于提示编译器，Fn<'a>(in: &'a T) -> &'a T {}, 返回值的生命周期必须小于等于输入值
//! 3. fn main() { {} }。一个scope默认有一个生命周期'a，那么main里面的scope的生命周期就小于main的生命周期

struct Person<'a> { // 和类型参数类似，'a表示Person会用到一个生命周期参数
    fname: &'a str, 
    lname: &'a str,
} // Person这个scope默认有一个生命周期'b，这里意味着'b必须<='a

impl<'a> Person<'a> {
    // 静态函数不需要指明<'a>，因为impl<'a>已经指明过了
    fn new(fname: &'a str, lname: &'a str) -> Person<'a> {
        Person {
            fname,
            lname
        }
    }

    // 带有self参数的也不需要指明
    fn fullname(&self) -> String {
        format!("{} {}", self.fname, self.lname)
    }
}

pub fn test() {
    let player = Person::new("Serena", "Williams");
    let player_fullname = player.fullname();
    println!("Player should work: {}", player_fullname);

    let player2_fullname: String;
    {
        let player2 = Person::new("Julia", "Catholin");
        player2_fullname = player2.fullname();
    }
    println!("Player2's name should work: {}", player2_fullname);
}